package cn.zyq.charging.order.config;

import cn.zyq.charging.order.mqtt.MqttConsumer;
import cn.zyq.charging.order.mqtt.MqttContext;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**Mqtt客户端配置*/
@Configuration
public class MqttConfiguration {
    /** 用户名 */
    private String username="admin";
    /** 密码 */
    private String password="public_zyq";
    /** 连接地址(tcp协议连接的端口号是1883， 另一个端口号是18083) */
    private String host="tcp://localhost:1883";

    /**客户端id，如果客户端id相同，则后边的MqttClient会将之前的覆盖掉*/
    private String mqttClientId="orderServiceClient";

    //MqttClient mqttClient;

    @Autowired
    private MqttContext mqttContext;

    @Bean
    public MqttClient getMqttClient() throws Exception {
        //1.创建MqttClient对象
        //MqttClient mqttClient = new MqttClient(host, MqttClient.generateClientId());
        MqttClient mqttClient = new MqttClient(host, mqttClientId);
        //2.创建连接参数对象(MqttConnectOptions对象)
        MqttConnectOptions options=new MqttConnectOptions();
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setCleanSession(true);//清理session
        options.setAutomaticReconnect(true);//自动重连
        options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);//版本

        //3.设置回调对象(会自动回调MqttConsumer对象的回调方法)//此回调方法是异步调用的
        //mqttClient.setCallback(new MqttConsumer(mqttClient,orderSerivice));

        //这个设置回调对象的代码执行完毕不会等待回调方法执行完毕再继续执行后边内容
        // (创建回调对象MqttConsumer时，还要封装一个MqttContext数据访问层的对象)，
        //而是直接往下继续执行(如果MqttConsumer收到消息后会自动执行回调函数)


        //创建MQTT消费端： MqttConsumer对象。
        //回调对象MqttConsumer在自己用new关键字创建的时候还要封装一个MqttContext上下文对象
        //<里边封装了数据访问层对象OrderRepository<里边封装了保存成功订单数据和保存失败订单数据的访问层方法，及修改订单状态的方法>>
        //MqttConsumer对象是自己new出来的没有在spring容器中。所以不能在MqttConsumer对象中调用容器中的对象
        //所以可以在mqttContext中注入容器中的对象，然后将mqttContext通过构造方法传入到MqttConsumer对象中
        //(此时MqttConsumer对象就可以使用spring容器中的对象了)
        MqttConsumer mqttConsumer=new MqttConsumer(mqttClient,mqttContext);
        //mqtt客户端对象设置：MQTT消费端MqttConsumer对象
        mqttClient.setCallback(mqttConsumer);

        //另一种写法:
        /*MqttConsumer mqttConsumer=new MqttConsumer();
        mqttConsumer.setMqttClient(mqttClient);
        mqttClient.setCallback(mqttConsumer);*/

        //4.基于上边的配置进行连接(不会等待回调方法执行完毕才用connect连接mqtt服务端)
        mqttClient.connect(options);
        return mqttClient;
    }

}
